/*
 * TimingEngine.cpp
 *
 *  Created on: 2010-11-22
 *      Author: leo
 */

#include "TimingEngine.h"
#include <iostream>
#include <boost/date_time/posix_time/posix_time.hpp>

#ifndef TEST_THREAD
#define TEST_THREAD
#endif

namespace GTD {

bool TimingEngine::_adminStop = false;
bool TimingEngine::_routineStop = false;
Tasks TimingEngine::_tasks;
thread* TimingEngine::_ptimerThread=NULL;
thread* TimingEngine::_padminThread=NULL;
boost::mutex TimingEngine::_tasksMutex;

TimingEngine::TimingEngine()
{
	// start 2 threads

}

TimingEngine::~TimingEngine() {
	// stop threads
	// dector
	if (_ptimerThread) delete _ptimerThread;
	if (_padminThread) delete _padminThread;
}

void	TimingEngine::startEngine()
{
	_ptimerThread = new thread(timingRoutine);
	_padminThread = new thread(adminRoutine);
//	_ptimerThread->detach();
//	_padminThread->detach();
}


void	TimingEngine::stopEngine()
{
	_routineStop = _adminStop = true;
}

void	TimingEngine::timingRoutine()
{
	while (!_routineStop) {
		// TODO: routine worker
#ifdef TEST_THREAD
		std::cout << "timingRoutine running... still " << _tasks.size() << std::endl;
#endif

		// TODO:check the task to notify
		//
		sleep(3);
	}
#ifdef TEST_THREAD
	std::cout << "end of work routine" << std::endl;
#endif
}

void	TimingEngine::adminRoutine()
{
	while (!_adminStop) {
		// TODO: admin worker
#ifdef TEST_THREAD
		std::cout << "adminRoutine running..."  << std::endl;
#endif
		sleep(5);
	}
#ifdef TEST_THREAD
	std::cout << "end of admin routine" << std::endl;
#endif
}

void TimingEngine::registTask(LocalTask task)
{
	// TODO protection for the shared var: _tasks
	_tasksMutex.lock();
	// Add task entry into _tasks
	if (_tasks.empty()) {
		_tasks.push_back(task);
#ifdef TEST_THREAD
		std::cout << "_tasks add 1st item.." << endl;
#endif
		_tasksMutex.unlock();
		return;
	}

	Tasks::iterator _itor = _tasks.begin();
	for (; _itor != _tasks.end(); _itor++) {
		// TODO: sort and add items by start
		if (!earlier(*_itor, task)) {
			_tasks.insert(_itor, task);
#ifdef TEST_THREAD
			std::cout << _tasks.size() << " tasks alive..." << std::endl;
#endif
		}
	}
	_tasks.insert(_itor, task);
	_tasksMutex.unlock();
}

void TimingEngine::dumpTasks()
{
	_tasksMutex.lock();
	Tasks::iterator _itor = _tasks.begin();
	for (; _itor != _tasks.end(); _itor++) {
		std::cout << *_itor << std::endl;
	}
	_tasksMutex.unlock();
}
size_t GTD::TimingEngine::getTasksCnt()
{
	return _tasks.size();
}
}
